﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.IO;
using System.Collections;

using Effects.Effects;

namespace Effects.Application
{

    /// <summary>
    ///  Loads effect from DLL (or more generally .NET assembly)
    /// </summary>
    /// <remarks>
    /// <para> This class loads classes from builded DLL file. It goes through file specified in constructor and looks for classes that are ancestors
    ///  of Effect.   .Effect. List of this classes can be later accessed via GetEffects method.</para>
    ///  <example>
    ///  <code>
    ///   EffectLoader load = new EffectLoader("MyDLL.dll");
    ///   load.Load();
    ///   .
    ///   .
    ///   .
    ///   Type[] availibleEffects = load.GetEffects();
    ///  </code>
    ///  </example>
    /// </remarks>
    class EffectFromDLLLoader
    {
        /// <summary>
        ///  Path to the DLL file
        /// </summary>
        private string file;

        /// <summary>
        ///  List of Types of Effects stored in given file.
        /// </summary>
        private List<Type> effectsInFile;

        /// <summary>
        ///  Member that stores <see cref="M:Effect.GetType"/> , It is used when checking whether class are ancestors of <see cref="Effect"/> class.
        /// </summary>
        private Type effectType;

        /// <summary>
        ///  Indicates whether file was successfully loaded.
        /// </summary>
        private bool fileOk;

        /// <summary>
        ///  Creates new instance that can load effects from given file.
        /// </summary>
        /// <param name="file"> path to the DLL file </param>
        public EffectFromDLLLoader(string file)
        {
            this.file = file;
            effectType = typeof(Effect);
        }

        /// <summary>
        ///  Loads effects.
        /// </summary>
        public void Load()
        {
            try
            {
                Assembly assemblyFromFile = Assembly.LoadFile(file);
                Type[] types = assemblyFromFile.GetTypes();

                effectsInFile = new List<Type>();
                foreach (Type t in types)
                {
                    if (t.IsSubclassOf(effectType))
                    {
                        effectsInFile.Add(t);
                    }
                }

                fileOk = true;
            }
            catch (Exception)
            {
                // some files is corrupted
                fileOk = false;
            }
        }

        /// <summary>
        ///  Returns list of all effects that are stored in given file.
        /// </summary>
        /// <returns> Array of availible effects. </returns>
        public Type[] GetEffects()
        {
            return effectsInFile.ToArray();
        }


        /// <summary>
        ///  Indicates whether file was succesfully loaded.
        /// </summary>
        /// <returns></returns>
        public bool  FileOk()
        {
            return fileOk;
        }
    }
}